/*******************************************************************************
 *                                 AWorks
 *                       ----------------------------
 *                       innovating embedded platform
 *
* Copyright (c) 2001-present Guangzhou ZHIYUAN Electronics Co., Ltd.
* ALL rights reserved.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* The License of this software follows LGPL v2.1, See the LICENSE for more details:
* https://opensource.org/licenses/LGPL-2.1
*
* Contact information:
* web site:    http://www.zlg.cn/
*******************************************************************************/
#ifndef __HPM_ROMAPI_XPI_DEF_H__
#define __HPM_ROMAPI_XPI_DEF_H__

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

/* \brief XPI 引脚定义 */
#define XPI_1PAD                  (0U)      /* 单引脚 */
#define XPI_2PADS                 (1U)      /* 双引脚 */
#define XPI_4PADS                 (2U)      /* 四引脚 */
#define XPI_8PADS                 (3U)      /* 八引脚 */

/* \brief XPI 阶段定义 */
#define XPI_PHASE_STOP            (0x00U)   /**< Phase: Stop */
#define XPI_PHASE_CMD_SDR         (0x01U)   /**< Phase: Send CMD in SDR mode */
#define XPI_PHASE_RADDR_SDR       (0x02U)   /**< Phase: Send Row Address in SDR Mode */
#define XPI_PHASE_CADDR_SDR       (0x03U)   /**< Phase: Send Column Address in SDR Mode */
#define XPI_PHASE_MODE4_SDR       (0x06U)   /**< Phase: Send Mode 4 in SDR Mode */
#define XPI_PHASE_MODE8_SDR       (0x07U)   /**< Phase: Send Mode 8 in SDR Mode */
#define XPI_PHASE_WRITE_SDR       (0x08U)   /**< Phase: Write data in SDR Mode */
#define XPI_PHASE_READ_SDR        (0x09U)   /**< Phase: Read data in SDR Mode */
#define XPI_PHASE_DUMMY_SDR       (0X0CU)   /**< Phase: Send Dummy in SDR Mode */
#define XPI_PHASE_DUMMY_RWDS_SDR  (0x0DU)   /**< Phase: Send Dummy RWDS  in SDR Mode */

#define XPI_PHASE_CMD_DDR         (0x21U)   /**< Phase: Send CMD in DDR Mode */
#define XPI_PHASE_RADDR_DDR       (0x22U)   /**< Phase: Send Raw Address in DDR Mode */
#define XPI_PHASE_CADDR_DDR       (0x23U)   /**< Phase: Send Column address in DDR Mode */
#define XPI_PHASE_MODE4_DDR       (0x26U)   /**< Phase: Send Mode 4 in DDR Mode */
#define XPI_PHASE_MODE8_DDR       (0x27U)   /**< Phase: Send Mode 8 in DDR Mode */
#define XPI_PHASE_WRITE_DDR       (0x28U)   /**< Phase: Write data in DDR Mode */
#define XPI_PHASE_READ_DDR        (0x29U)   /**< Phase: Read data in SDR Mode */
#define XPI_PHASE_DUMMY_DDR       (0x2CU)   /**< Phase: Send DUMMY in DDR Mode */
#define XPI_PHASE_DUMMY_RWDS_DDR  (0x2DU)   /**< Phase: Send DUMMY RWDS in DDR Mode */

/* \brief 生成一个子指令*/
#define SUB_INSTR(phase, pad, op) ((uint32_t)(((uint16_t)(phase) << 10) | ((uint16_t)(pad) << 8) | ((uint16_t)(op))))
/* \brief 生成一个字的指令序列*/
#define XPI_INSTR_SEQ(phase0, pad0, op0, phase1, pad1, op1) (SUB_INSTR(phase0, pad0, op0) | (SUB_INSTR(phase1, pad1, op1)<<16))

typedef uint32_t XPI_Type;

/* \brief XPI 传输通道类型定义 */
typedef enum {
    xpi_xfer_channel_a1,       /**< The address is based on the device connected to Channel A1 */
    xpi_xfer_channel_a2,       /**< The address is based on the device connected to Channel A2 */
    xpi_xfer_channel_b1,       /**< The address is based on the device connected to Channel B1 */
    xpi_xfer_channel_b2,       /**< The address is based on the device connected to Channel B2 */
    xpi_xfer_channel_auto,     /**< The channel is auto determined */
} xpi_xfer_channel_t;

/* \brief XPI 通道定义 */
typedef enum {
    xpi_channel_a1,                 /* 端口：通道 A1 */
    xpi_channel_a2,                 /* 端口：通道 A2 */
    xpi_channel_b1,                 /* 端口：通道 B1 */
    xpi_channel_b2,                 /* 端口：通道 B2 */
} xpi_channel_t;

/* \brief XPI APB 传输类型 */
typedef enum {
    xpi_apb_xfer_type_cmd,          /* APB 命令类型：只命令 */
    xpi_apb_xfer_type_config,       /* APB 命令类型：配置 */
    xpi_apb_xfer_type_read,         /* APB 命令类型：读 */
    xpi_apb_xfer_type_write,        /* APB 命令类型：写 */
} xpi_apb_xfer_type_t;

/* \brief XPI 传输环境结构体*/
typedef struct {
    uint32_t  addr;          /**< device address for XPI transfer */
    uint8_t   channel;       /**< channel for XPI transfer */
    uint8_t   cmd_type;      /**< command type for XPI transfer */
    uint8_t   seq_idx;       /**< Sequence index for XPI transfer */
    uint8_t   seq_num;       /**< Sequence number for XPI transfer */
    uint32_t *buf;           /**< Buffer for XPI transfer */
    uint32_t  xfer_size;     /**< Transfer size in bytes */
} xpi_xfer_ctx_t;

/* \brief XPI 指令序列*/
typedef struct {
    uint32_t entry[4];
} xpi_instr_seq_t;

/* \brief XPI 配置结构体*/
typedef struct {
    uint8_t  rxclk_src;                  /**< Read sample clock source */
    uint8_t  reserved0[7];
    uint8_t  tx_watermark_in_dwords;     /**< Tx watermark in double words */
    uint8_t  rx_watermark_in_dwords;     /**< Rx watermark in double words */
    uint8_t  enable_differential_clk;    /**< Enable differential clock */
    uint8_t  reserved1[5];
    uint32_t access_flags;               /**< Access flags */
} xpi_config_t;

/* \brief XPI 设备配置结构体*/
typedef struct {
    uint32_t size_in_kbytes;             /**< Device size in kbytes */
    uint32_t serial_root_clk_freq;       /**< XPI serial root clock frequency */

    uint8_t  enable_write_mask;          /**< Enable write mask, typically for PSRAM/HyperRAM */
    uint8_t  data_valid_time;            /**< Data valid time, Unit 0.1ns */
    uint8_t  reserved0[2];

    uint8_t  cs_hold_time;               /**< CS hold time, cycles in terms of FLASH clock */
    uint8_t  cs_setup_time;              /**< CS setup time, cycles in terms of FLASH clock */
    uint16_t cs_interval;                /**< CS interval, cycles in terms of FLASH clock */

    uint8_t  reserved1;
    uint8_t  column_addr_size;           /**< Column address bits */
    uint8_t  enable_word_address;        /**< Enable word address, for HyperFLASH/HyperRAM */
    uint8_t  dly_target;                 /**< Delay target */

    uint8_t  ahb_write_seq_idx;          /**< AHB write sequence index */
    uint8_t  ahb_write_seq_num;          /**< AHB write sequence number */
    uint8_t  ahb_read_seq_idx;           /**< AHB read sequence index */
    uint8_t  ahb_read_seq_num;           /**< AHB read sequence number */

    uint8_t  ahb_write_wait_interval;    /**< AHB write wait interval, in terms of FLASH clock */
    uint8_t  reserved2[3];
} xpi_device_config_t;

#endif /* __HPM_ROMAPI_XPI_DEF_H__ */
